/*
 * main.cc
 *
 *  Created on: Nov 25, 2010
 *      Author: fify
 */

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>

using namespace std;

inline int get_num(char ch)
{
	switch(ch)
	{
	case 'A':
		return 0;
	case 'T':
		return 1;
	case 'G':
		return 2;
	case 'C':
		return 3;
	}

	return -1;
}

class Node
{
public:
	int count;	// How many times it occurs.

	int child[4];

	void init()
	{
		count = 0;
		memset(child, 0, sizeof(child));
	}
};

class Mark
{
public:
	int index;
	int mark;

	Mark(){};
	Mark(int i, int m)
	{
		index = i;
		mark = m;
	}

	bool operator < (const Mark m) const
	{
		return mark < m.mark;
	}
};

Node trie[(1 << 20) + 5];
int top;	// Top node of the trie tree.
char dna[20005][21];
Mark marks[20005];
int result[20005];

int n, m;

void init_trie()
{
	top = 1;
	trie[0].init();
}

int insert(char * str, int len)
{
	int now = 0, child;
	for(int i = 0;i < len;i++)
	{
		child = get_num(str[i]);
		if(trie[now].child[child])
		{
			now = trie[now].child[child];
		}
		else
		{
			now = trie[now].child[child] = top ++;
			trie[now].init();
		}
	}

	trie[now].count ++;

	return now;
}

void set_mark(int k)
{
	init_trie();

	int temp;
	for(int i = 0;i<n;i++)
	{
		temp = insert(dna[i], k);
		marks[i].mark = temp;
		marks[i].index = i;
	}
}
void solve()
{
	set_mark(m / 2);

	sort(marks, marks + n);

	memset(result, 0, sizeof(result[0]) * n + 1);

	int mk = -1;
	int temp;
	for(int i = 0;i<n;i++)
	{
		if(marks[i].mark != mk)
		{
			init_trie();
			mk = marks[i].mark;
		}

		temp = insert(dna[marks[i].index] + m / 2, m - m / 2);
		temp = trie[temp].count;

		++result[temp];
		--result[temp - 1];
	}

	for(int i = 1;i<=n;i++)
	{
		printf("%d\n", result[i]);
	}
}

int main()
{
	while(scanf("%d%d", &n, &m))
	{
		if(n == 0 && m == 0)
			return 0;

		for(int i = 0;i<n;i++)
		{
			scanf("%s", dna[i]);
		}
		solve();
	}
}
